// Model types for handlers compatibility
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

// User models
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
    pub id: i64,
    pub email: String,
    pub hashed_password: String,
    pub avatar_url: Option<String>,
    pub is_admin: bool,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

impl User {
    pub fn is_admin_bool(&self) -> bool {
        self.is_admin
    }
}

impl From<User> for UserResponse {
    fn from(user: User) -> Self {
        UserResponse {
            id: user.id,
            email: user.email,
            avatar_url: user.avatar_url,
            is_admin: user.is_admin,
            created_at: user.created_at,
        }
    }
}

#[derive(Debug, Deserialize)]
pub struct UserCreate {
    pub email: String,
    pub password: String,
}

#[derive(Debug, Deserialize)]
pub struct UserLogin {
    pub email: String,
    pub password: String,
}

#[derive(Debug, Serialize)]
pub struct UserResponse {
    pub id: i64,
    pub email: String,
    pub avatar_url: Option<String>,
    pub is_admin: bool,
    pub created_at: DateTime<Utc>,
}

#[derive(Debug, Serialize)]
pub struct Token {
    pub access_token: String,
    pub token_type: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
    pub sub: String, // Subject (user email)
    pub exp: usize,  // Expiration time
    pub iat: usize,  // Issued at
}

// Data item models
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataItem {
    pub id: i64,
    pub name: String,
    pub description: Option<String>,
    pub project: Option<String>,
    pub source: String,
    pub file_path: String,
    pub file_hash: Option<String>,
    pub file_size: Option<i64>,
    pub file_type: Option<String>,
    pub is_folder: bool,
    pub file_count: Option<i64>,
    pub user_id: i64,
    pub parent_id: Option<i64>,
    pub is_public: bool,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub dvc_metadata_id: Option<i64>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataItemWithUser {
    pub id: i64,
    pub name: String,
    pub description: Option<String>,
    pub project: Option<String>,
    pub source: String,
    pub file_path: String,
    pub file_hash: Option<String>,
    pub file_size: Option<i64>,
    pub file_type: Option<String>,
    pub is_folder: bool,
    pub file_count: Option<i64>,
    pub user_id: i64,
    pub parent_id: Option<i64>,
    pub is_public: bool,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub dvc_metadata_id: Option<i64>,
    pub user_email: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NewDataItem {
    pub name: String,
    pub description: Option<String>,
    pub project: Option<String>,
    pub source: String,
    pub file_path: String,
    pub file_hash: Option<String>,
    pub file_size: Option<i64>,
    pub file_type: Option<String>,
    pub is_folder: bool,
    pub file_count: Option<i64>,
    pub user_id: i64,
    pub parent_id: Option<i64>,
    pub is_public: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UnifiedDataItem {
    pub data_item: DataItemWithUser,
    pub dvc_metadata: Option<DataItemWithUser>,
    pub actual_file_path: String,
    pub has_dvc_metadata: bool,
}

// Lineage models
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataLineage {
    pub id: i64,
    pub child_id: i64,
    pub parent_id: i64,
    pub relationship_type: String,
    pub confidence: f64,
    pub detection_method: String,
    pub description: Option<String>,
    pub created_by: i64,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataLineageWithDetails {
    pub id: i64,
    pub child_id: i64,
    pub parent_id: i64,
    pub relationship_type: String,
    pub confidence: f64,
    pub detection_method: String,
    pub description: Option<String>,
    pub created_by: i64,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub child_name: String,
    pub child_path: String,
    pub child_size: Option<i64>,
    pub child_user_id: i64,
    pub child_public: bool,
    pub parent_name: String,
    pub parent_path: String,
    pub parent_size: Option<i64>,
    pub parent_user_id: i64,
    pub parent_public: bool,
    pub created_by_email: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NewDataLineage {
    pub child_id: i64,
    pub parent_id: i64,
    pub relationship_type: String,
    pub confidence: f64,
    pub detection_method: String,
    pub description: Option<String>,
    pub created_by: i64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataItemWithFullLineage {
    pub data_item: DataItemWithUser,
    pub parents: Vec<DataItemWithUser>,
    pub children: Vec<DataItemWithUser>,
    pub lineage_count: i64,
    pub upstream_count: i64,
    pub downstream_count: i64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LineageGraph {
    pub nodes: Vec<LineageGraphNode>,
    pub edges: Vec<LineageGraphEdge>,
    pub root_nodes: Vec<i64>,
    pub leaf_nodes: Vec<i64>,
    pub total_nodes: i64,
    pub total_edges: i64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LineageGraphNode {
    pub id: i64,
    pub name: String,
    pub file_type: Option<String>,
    pub file_size: Option<i64>,
    pub user_email: String,
    pub project: Option<String>,
    pub created_at: DateTime<Utc>,
    pub node_type: String,
    pub level: Option<i32>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LineageGraphEdge {
    pub from: i64,
    pub to: i64,
    pub relationship_type: String,
    pub confidence: f64,
    pub detection_method: String,
    pub created_by: String,
    pub created_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LineageStats {
    pub total_relationships: i64,
    pub relationships_by_type: Vec<(String, i64)>,
    pub relationships_by_method: Vec<(String, i64)>,
    pub average_confidence: f64,
    pub high_confidence_relationships: i64,
    pub pending_suggestions: i64,
    pub auto_detected_relationships: i64,
    pub manual_relationships: i64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LineagePath {
    pub path: Vec<DataItemWithUser>,
    pub relationships: Vec<DataLineage>,
    pub path_length: i64,
    pub total_size: i64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LineageSuggestion {
    pub id: i64,
    pub child_id: i64,
    pub suggested_parent_id: i64,
    pub confidence_score: f64,
    pub suggestion_reason: String,
    pub detection_method: String,
    pub status: String,
    pub created_at: DateTime<Utc>,
    pub reviewed_at: Option<DateTime<Utc>>,
    pub reviewed_by: Option<i64>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LineageSuggestionWithDetails {
    pub id: i64,
    pub child_id: i64,
    pub suggested_parent_id: i64,
    pub confidence_score: f64,
    pub suggestion_reason: String,
    pub detection_method: String,
    pub status: String,
    pub created_at: DateTime<Utc>,
    pub reviewed_at: Option<DateTime<Utc>>,
    pub reviewed_by: Option<i64>,
    pub child_name: String,
    pub child_user_id: i64,
    pub parent_name: String,
    pub parent_user_id: i64,
    pub reviewed_by_email: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NewLineageSuggestion {
    pub child_id: i64,
    pub suggested_parent_id: i64,
    pub confidence_score: f64,
    pub suggestion_reason: String,
    pub detection_method: String,
}

// Request/Response DTOs
#[derive(Debug, Deserialize)]
#[allow(dead_code)]
pub struct CreateLineageRequest {
    pub child_id: i64,
    pub parent_id: i64,
    pub relationship_type: String,
    pub description: Option<String>,
}

#[derive(Debug, Deserialize)]
#[allow(dead_code)]
pub struct UpdateLineageRequest {
    pub relationship_type: Option<String>,
    pub description: Option<String>,
}

#[derive(Debug, Deserialize)]
#[allow(dead_code)]
pub struct ProcessLineageSuggestionsRequest {
    pub suggestion_id: i64,
    pub action: String,
    pub relationship_type: Option<String>,
    pub description: Option<String>,
}

#[derive(Debug, Serialize)]
pub struct LineageSuggestionResponse {
    pub suggestion: LineageSuggestionWithDetails,
    pub similar_relationships: Vec<DataLineageWithDetails>,
}

// DVC Metadata models
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DvcMetadata {
    pub id: i64,
    pub user_id: i64,
    pub dvc_filename: String,
    pub data_filename: String,
    pub data_file_hash: String,
    pub data_file_size: Option<i64>,
    pub dvc_file_path: Option<String>,
    pub dvc_file_hash: Option<String>,
    pub project: Option<String>,
    pub source: String,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NewDvcMetadata {
    pub user_id: i64,
    pub dvc_filename: String,
    pub data_filename: String,
    pub data_file_hash: String,
    pub data_file_size: Option<i64>,
    pub dvc_file_path: Option<String>,
    pub dvc_file_hash: Option<String>,
    pub project: Option<String>,
    pub source: String,
}
